package org.xuk.spring.ws.inteceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.stereotype.Component;
import org.xuk.spring.ws.constants.WsConstants;
import org.xuk.spring.ws.model.UserSession;
import org.xuk.spring.ws.model.UserSessionPrincipal;
import org.xuk.spring.ws.utils.TokenUtil;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Component
public class WebSocketInboundInterceptor implements ChannelInterceptor {
    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (accessor == null) {
            return message;
        }

        //建立连接
        if (Objects.equals(accessor.getCommand(), StompCommand.CONNECT)) {
            connect(message, accessor);
        }
        return message;
    }

    /**
     * 建立会话
     *
     * @param message
     * @param accessor
     */
    private void connect(Message<?> message, StompHeaderAccessor accessor) {
        String token = accessor.getFirstNativeHeader(WsConstants.TOKEN_HEADER);
        if (StringUtils.isEmpty(token)) {
            throw new MessageDeliveryException("token missing!");
        }
        String userId = TokenUtil.parseToken(token);
        if (StringUtils.isEmpty(userId)) {
            throw new MessageDeliveryException("userId missing!");
        }
        String simpleSessionId = (String) message.getHeaders().get(SimpMessageHeaderAccessor.SESSION_ID_HEADER);

        UserSession userSession = new UserSession();
        userSession.setSimpleSessionId(simpleSessionId);
        userSession.setUserId(userId);
        userSession.setCreateTime(LocalDateTime.now());
        //关联用户的会话。通过msgOperations.convertAndSendToUser(username, "/topic/subNewMsg", msg); 此方法，可以发送给用户消息
        accessor.setUser(new UserSessionPrincipal(userSession));
    }
}
